package com.ccx.demo.business.code.service;

import com.alibaba.fastjson.JSON;
import com.ccx.demo.business.code.entity.TabValid;
import com.querydsl.core.QueryResults;
import com.support.mvc.entity.base.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author 谢长春 2018/12/20
 */
@Slf4j
@Service

@Validated
public class ValidService {

    public String hasNull(@Null String arg) {
        return (Objects.toString(arg));
    }

    public String notNull(@NotNull String arg) {
        return (Objects.toString(arg));
    }

    public String notBlank(@NotBlank String arg) {
        return (Objects.toString(arg));
    }

    public String size(@Size(min = 1, max = 10) String arg) {
        return (Objects.toString(arg));
    }

    public String pattern(@Pattern(regexp = "\\w+") String arg) {
        return (Objects.toString(arg));
    }

    public String notEmpty(@NotEmpty List<@NotBlank String> arg) {
        return (Objects.toString(arg));
    }

    public String min(@Min(1) Integer arg) {
        return (Objects.toString(arg));
    }

    public String max(@Max(10) Integer arg) {
        return (Objects.toString(arg));
    }

    public String decimalMin(@DecimalMin("1.00") BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String decimalMax(@DecimalMax("10.0") BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String digits(@Digits(integer = 10, fraction = 2) BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String negative(@Negative BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String negativeOrZero(@NegativeOrZero BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String positive(@Positive BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String positiveOrZero(@PositiveOrZero BigDecimal arg) {
        return (Objects.toString(arg));
    }

    public String assertTrue(@AssertTrue Boolean arg) {
        return (Objects.toString(arg));
    }

    public String assertFalse(@AssertFalse Boolean arg) {
        return (Objects.toString(arg));
    }

    public String email(@Email String arg) {
        return (Objects.toString(arg));
    }

    public String past(@Past Date arg) {
        return (Objects.toString(arg));
    }

    public String future(@Future Date arg) {
        return (Objects.toString(arg));
    }

    // IBaseService Start **************************************************************************************************

    /**
     * 保存；
     *
     * @param obj    TabValid 实体对象
     * @param userId {@link Long} 操作用户ID
     * @return TabValid 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    public @NotNull(message = "返回值不能为null") TabValid save(
            @Valid @NotNull(message = "【obj】不能为null") final TabValid obj,
            @NotNull(message = "【userId】不能为null") @Positive(message = "【userId】必须大于0") final Long userId) {
        log.info(JSON.toJSONString(Arrays.asList(obj, userId)));
        if (Objects.equals((short) 10, obj.getValue())) return null;
        return obj;
    }

    /**
     * 批量保存；
     *
     * @param list   {@link List<TabValid>}  实体对象集合
     * @param userId {@link Long} 操作用户ID
     * @return List<TabValid> 实体对象集合
     */
    @Transactional(rollbackFor = Exception.class)
    public @NotNull(message = "返回值不能为null") List<TabValid> saveAll(
            @NotEmpty(message = "【list】不能为空") final List<@Valid @NotNull TabValid> list,
            @NotNull(message = "【userId】不能为null") @Positive(message = "【userId】必须大于0") final Long userId) {
        log.info(JSON.toJSONString(Arrays.asList(list, userId)));
        if (Objects.equals((short) 10, list.get(0).getValue())) return null;
        return list;
    }

    /**
     * 更新数据；
     *
     * @param id     {@link Long} 数据ID
     * @param userId {@link Long} 操作用户ID
     * @param obj    TabValid 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id,
            @NotNull(message = "【userId】不能为null") @Positive(message = "【userId】必须大于0") final Long userId,
            @Valid @NotNull(message = "【obj】不能为null") final TabValid obj) {
        log.info(JSON.toJSONString(Arrays.asList(id, userId, obj)));
    }

    /**
     * 按ID删除，物理删除；执行物理删除前先查询到数据，等待删除成功之后返回该数据对象，通过 AOP 拦截记录到删除日志中
     *
     * @param id     {@link Long} 数据ID
     * @param userId {@link Long} 操作用户ID
     * @return E 删除对象数据实体
     */
    @Transactional(rollbackFor = Exception.class)
    public TabValid deleteById(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id,
            @NotNull(message = "【userId】不能为null") @Positive(message = "【userId】必须大于0") final Long userId) {
        log.info(JSON.toJSONString(Arrays.asList(id, userId)));
        return null;
    }

    /**
     * 按ID删除，逻辑删除
     *
     * @param id     {@link Long} 数据ID
     * @param userId {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteById(
            @NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id,
            @NotNull(message = "【userId】不能为null") @Positive(message = "【userId】必须大于0") final Long userId) {
        log.info(JSON.toJSONString(Arrays.asList(id, userId)));
    }

    /**
     * 批量操作按ID删除，逻辑删除
     *
     * @param ids    {@link List<Long>} 数据ID
     * @param userId {@link Long} 操作用户ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteByIds(
            @NotEmpty(message = "【ids】不能为空") final Set<@NotNull @Positive Long> ids,
            @NotNull(message = "【userId】不能为null") @Positive(message = "【userId】必须大于0") final Long userId) {
        log.info(JSON.toJSONString(Arrays.asList(ids, userId)));
    }


    // IBaseService End && IOpenService Start ****************************************************************************

    /**
     * 保存；
     *
     * @param obj TabValid 实体对象
     * @return TabValid 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    public @NotNull(message = "返回值不能为null") TabValid save(
            @Valid @NotNull(message = "【obj】不能为null") final TabValid obj) {
        log.info(JSON.toJSONString(obj));
        if (Objects.equals((short) 10, obj.getValue())) return null;
        return obj;
    }

    /**
     * 批量保存；
     *
     * @param list {@link List<TabValid>}  实体对象集合
     * @return List<TabValid> 实体对象集合
     */
    @Transactional(rollbackFor = Exception.class)
    public @NotNull(message = "返回值不能为null") List<TabValid> saveAll(
            @NotEmpty(message = "【list】不能为空") final List<@Valid @NotNull TabValid> list) {
        log.info(JSON.toJSONString(list));
        if (Objects.equals((short) 10, list.get(0).getValue())) return null;
        return list;
    }

    /**
     * 更新数据
     *
     * @param id  {@link Long} 数据ID
     * @param obj TabValid 实体对象
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(@NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id,
                       @Valid @NotNull(message = "【obj】不能为null") final TabValid obj) {
        log.info(JSON.toJSONString(Arrays.asList(id, obj)));
    }

    /**
     * 按ID删除，物理删除；执行物理删除前先查询到数据，等待删除成功之后返回该数据对象，通过 AOP 拦截记录到删除日志中
     *
     * @param id {@link Long} 数据ID
     * @return TabValid 删除对象数据实体
     */
    @Transactional(rollbackFor = Exception.class)
    public TabValid deleteById(@NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id) {
        log.info(JSON.toJSONString(id));
        return null;
    }

    /**
     * 按ID删除，逻辑删除
     *
     * @param id {@link Long} 数据ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteById(@NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id) {
        log.info(JSON.toJSONString(id));
    }

    /**
     * 批量操作按ID删除，逻辑删除
     *
     * @param ids {@link List<Long>} 数据ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void markDeleteByIds(@NotEmpty(message = "【ids】不能为空") final Set<@NotNull @Positive Long> ids) {
        log.info(JSON.toJSONString(ids));
    }

    // IOpenService End **********************************************************************************************

    /**
     * 按ID查询对象
     *
     * @param id {@link Long} 数据ID
     * @return {@link Optional<TabValid>} 实体对象
     */
    public Optional<TabValid> findById(@NotNull(message = "【id】不能为null") @Positive(message = "【id】必须大于0") final Long id) {
        log.info(Objects.toString(id));
        return Optional.of(TabValid.builder().id(id).build());
    }

    /**
     * 按条件查询列表
     *
     * @param condition TabValid 查询条件
     * @return {@link List<TabValid>} 结果集合
     */
    public @NotNull(message = "返回值不能为null") List<TabValid> list(
            @NotNull(message = "【condition】不能为null") final TabValid condition) {
        log.info(JSON.toJSONString(condition));
        if (Objects.equals((short) 10, condition.getValue())) return null;
        return Collections.singletonList(condition);
    }

    /**
     * 按条件分页查询列表
     *
     * @param condition TabValid 查询条件
     * @param page      {@link Page} 分页排序集合
     * @return {@link QueryResults<TabValid>} 分页对象
     */
    public @NotNull(message = "返回值不能为null") QueryResults<TabValid> page(
            @NotNull(message = "【condition】不能为null") final TabValid condition, final Page page) {
        log.info(JSON.toJSONString(Arrays.asList(condition, page)));
        if (Objects.equals((short) 10, condition.getValue())) return null;
        return new QueryResults<>(Collections.singletonList(condition), 1L, 1L, 1L);
    }
}
